package com.tqjc.business.interactivewithscan.core.thread.truck;

import com.tqjc.business.interactivewithscan.consts.CoordConstant;
import com.tqjc.business.interactivewithscan.core.data.AskData.AskData;
import com.tqjc.business.interactivewithscan.core.data.PointData.PointData;
import com.tqjc.business.interactivewithscan.core.operation.SpecificOperation;
import com.tqjc.business.interactivewithscan.core.thread.NormalThread;
import com.tqjc.business.interactivewithscan.entity.*;
import com.tqjc.business.interactivewithscan.service.ScanDeviceDataService;
import com.tqjc.business.interactivewithscan.service.UfcDeviceInfoService;
import com.tqjc.business.interactivewithscan.service.impl.ScanDeviceDataServiceImpl;
import com.tqjc.business.interactivewithscan.uils.CoordinatesUtils;
import com.tqjc.business.interactivewithscan.uils.PTZUtils;
import com.tqjc.business.interactivewithscan.uils.TiancheUtils;
import com.tqjc.system.core.util.SpringUtils;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

/**
 * @program: C20005_Xianggang_new
 * @description: 废钢跨货车扫描线程
 * @author: Patienyon
 * @create: 2023-11-06 20:07
 **/

//@Component
public class ScrapSteelScanScanTruckThread extends NormalThread {

    private ScanDeviceDataService scanDeviceDataService = SpringUtils.getBean(ScanDeviceDataServiceImpl.class);

    /**
     * 设备信息
     */
    private UfcDeviceInfoService deviceInfoService = SpringUtils.getBean(UfcDeviceInfoService.class);

    public ScrapSteelScanScanTruckThread() {
        //绑定当前的设备信息
        this.device = scanDeviceDataService.getById(200001);
        this.deviceInfo = deviceInfoService.getById(200001);
        this.start();

    }

    /**
     * 货车任务
     */
//    private UfcVehicleTask vehicleTask;
    @Override
    public void run() {
        while (true) {
            try {
                checkSocket();
                //获取当前的请求列表
                final Queue<AskData> tmpAskData = getAskDataQue();
                //假设当前的请求列表有，循环准备开始获取抓点/放点
                while (!tmpAskData.isEmpty()) {
                    Integer num = 0;
                    AskData askData = tmpAskData.poll();

                    //读取当前的请求
                    //获取当前请求ID
                    String askId = askData.getAskId();
                    //获取当前的工作模式
                    String type = askData.getType();
                    //获取当前需要获取的区域ID
                    Long areaId = Long.parseLong(askData.getAreaId());
                    //所属跨
                    Integer scanId = askData.getScanType();

                    tmpAskData.poll();
                    while (num < 3) {
//                    先获取扫描数据
                        //获取放点
                        List<Coord> discharges = getGrabCoords();
                        if (!discharges.isEmpty()) {
                            addResponseMap(askId, new PointData(true, "获取抓点成功", discharges, new Timestamp(System.currentTimeMillis())));
                            break;
                        }

                        num++;
                        if (num >= 3) {
                            addResponseMap(askId, new PointData(false, "获取抓点失败"));
                        }
                    }

                    askDataQue.poll();


                }

                Thread.sleep(30000);
                // 线程逻辑代码
            } catch (Exception e) {
                // 捕获线程异常
                e.printStackTrace();
                // 线程挂掉后，等待一段时间再重新启动
                try {
                    Thread.sleep(1000); // 可以根据需要调整等待时间
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }

    }

    public synchronized void addAskDataQue(AskData askData) {
        this.askDataQue.add(askData);
    }

    public synchronized void addResponseMap(String askId, PointData pointData) {
        this.responseMap.put(askId, pointData);
    }

    public List<Coord> getGrabCoords() {
        ScanningData scanning = PTZUtils.scanning(device, socketClient);

        try {
            List<Coord> areas = CoordinatesUtils.queryArea(scanning.getScanningArea(), device.getDeviceCode(), scanning.getScanningDate());
            if (areas.size() < 4) {
                return null;
            }
            int may = areas.stream().max(new CoordSort(3)).get().getY();
            int miy = areas.stream().min(new CoordSort(3)).get().getY();
            int max = areas.stream().max(new CoordSort(2)).get().getX();
            int mix = areas.stream().min(new CoordSort(2)).get().getX();
            int y = (may + miy) / 2;
            int x = (max + mix) / 2;
            int tx = (max - mix) / 2 - CoordConstant.Car_Safe_Distance;
            int ty = (may - miy) / 2 - CoordConstant.Car_Safe_Distance;
            Coord coord = new Coord(x, y, 0);
            QuadrilateralVertex vertex = CoordinatesUtils.queryVertex(coord, tx, ty);
            List<Coord> dems = CoordinatesUtils.yuntaiScanningHandle(scanning.getScanningDem());
            CoordinatesUtils.removeShadows(dems);
            if (dems.size() == 0) {
                return null;
            }
            int z = dems.stream().min(new CoordSort(4)).get().getZ();
            if (z < CoordConstant.Maximum_Height_To_Top) {
                return null;
            }
            List<Coord> screens = CoordinatesUtils.screenDesignationRegion(vertex, dems);
            Coord minCoord = screens.stream().min(new CoordSort(4)).get();
            // 货车已经卸料完成
            return getCoordData(vertex, screens);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
//        return null;
    }

    private List<Coord> getCoordData(QuadrilateralVertex vertex, List<Coord> screens) {
        CoordDataEntity grabData = getGrabCoordData();
        //去除阴影
        CoordinatesUtils.removeShadows(screens);
        // 一号先拿
        Integer type = device.getDeviceType() / 100000;
        SameSpanTianche tiancheInfo = TiancheUtils.settingTiancheInfo(deviceInfoService, type, true);
        Coord grab1 = CoordinatesUtils.grabTruckCoord(new ArrayList<>(screens), vertex, tiancheInfo, null);
        grabData.setOneFront(grab1);
        tiancheInfo = TiancheUtils.settingTiancheInfo(deviceInfoService, type, false);
        Coord grab2 = CoordinatesUtils.grabTruckCoord(new ArrayList<>(screens), vertex, tiancheInfo, grab1);
        grabData.setTwoAfter(grab2);
        //  二号先拿
        Coord grab3 = CoordinatesUtils.grabTruckCoord(new ArrayList<>(screens), vertex, tiancheInfo, null);
        grabData.setTwoFront(grab3);
        tiancheInfo = TiancheUtils.settingTiancheInfo(deviceInfoService, type, true);
        Coord grab4 = CoordinatesUtils.grabTruckCoord(new ArrayList<>(screens), vertex, tiancheInfo, grab3);
        grabData.setOneAfter(grab4);

        System.err.println("【" + device.getDeviceName() + "】本次四个吸料点如下：");
        System.err.println("【" + device.getDeviceName() + "】一号先拿：" + grab1);
        System.err.println("【" + device.getDeviceName() + "】二号后拿：" + grab2);
        System.err.println("【" + device.getDeviceName() + "】二号先拿：" + grab3);
        System.err.println("【" + device.getDeviceName() + "】一号后拿：" + grab4);
        return new ArrayList<Coord>() {{
            add(grab1);
            add(grab2);
            add(grab3);
            add(grab4);
        }};

    }

    @Override
    public void heartbeat(DeviceSocketClient socketClient) {
        NetSocket socket = socketClient.getSocket();
        System.err.println("【" + device.getDeviceName() + "】首次发送心跳！");
        socket.write(Buffer.buffer("HB"));
        socketClient.getVertx().setPeriodic(2000, t -> {
            socket.write(Buffer.buffer("HB"));
        });
    }

    private CoordDataEntity grabCoordData;

    public synchronized CoordDataEntity getGrabCoordData() {
        if (grabCoordData == null) {
            grabCoordData = new CoordDataEntity();
            grabCoordData.setSpan(device.getDeviceCode().substring(0, 3));
        }
        return grabCoordData;
    }

}
